﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using AgileTimeTracker.Client.Wpf.Common;
using AgileTimeTracker.Client.Wpf.Services;
using AgileTimeTracker.Domain.TaskModule;

namespace AgileTimeTracker.Client.Wpf.TimeControlModule
{
    public class TaskListViewModel : PageViewModel
    {
        private ObservableCollection<TaskWorkTimeItemViewModel> tasks;

        private ListCollectionView tasksView;

        private TaskWorkTimeItemViewModel selectedTask;

        public TaskListViewModel()
        {
            this.Title = "Task List";
        }

        public ListCollectionView TasksView
        {
            get { return this.tasksView; }
            set { this.OnPropertyChanged(ref this.tasksView, value); }
        }

        public ObservableCollection<TaskWorkTimeItemViewModel> Tasks
        {
            get { return this.tasks; }
            set { this.OnPropertyChanged(ref this.tasks, value); }
        }

        public TaskWorkTimeItemViewModel SelectedTask
        {
            get { return this.selectedTask; }
            set { this.OnPropertyChanged(ref this.selectedTask, value); }
        }

        protected override void Load()
        {
            base.Load();

            var tasks = AppService.Instance.GetTasks(
                    MainWindowViewModel.Instance.CurrentProject);

            if (this.tasks == null)
            {
                this.Tasks = new ObservableCollection<TaskWorkTimeItemViewModel>(tasks);
            }
            else
            {
                foreach (var task in this.tasks.Where(t => !tasks.Contains(t)).ToArray())
                {
                    this.tasks.Remove(task);
                }

                foreach (var task in tasks.Where(t => !this.tasks.Contains(t)))
                {
                    this.tasks.Add(task);
                }
            }

            if (this.tasksView == null)
            {
                var tasksView = new ListCollectionView(this.tasks);
                tasksView.GroupDescriptions.Add(new PropertyGroupDescription("IterationPath"));
                tasksView.GroupDescriptions.Add(new PropertyGroupDescription("UserStory"));
                this.TasksView = tasksView;
            }
            else
            {
                this.tasksView.Refresh();
                this.OnPropertyChanged("TaskView");
            }
        }

        public RelayCommand EditTaskCommand { get; set; }

        public void EditTask()
        {
            var view = new EditTaskViewModel(this.selectedTask.CurrentTask);
            view.OnRequestClose = () =>
            {
                this.RefreshTasks();
                MainWindowViewModel.Instance.TempView = null;
            };

            MainWindowViewModel.Instance.TempView = view;
        }

        public bool CanEditTask()
        {
            return this.selectedTask != null;
        }

        public RelayCommand AddNewTaskCommand { get; set; }

        public void AddNewTask()
        {
            var view = new EditTaskViewModel();            
            view.OnRequestClose = () =>
            {
                if (view.CurrentTask != null)
                {
                    this.tasks.Add(new TaskWorkTimeItemViewModel(view.CurrentTask));
                }

                MainWindowViewModel.Instance.TempView = null;
            };

            MainWindowViewModel.Instance.TempView = view;
        }

        

        public RelayCommand UpdateWorkItemsCommand { get; set; }

        public void UpdateWorkItems()
        {
            this.BlockUi("Updating work items...");
            Task.Run(() =>
            {
                foreach (var task in this.tasks)
                {
                    AppService.Instance.UpdateTaskFromTfs(
                        MainWindowViewModel.Instance.CurrentProject,
                        task.CurrentTask);
                }
            }).ContinueWith((t) =>
            {
                foreach (var task in this.tasks)
                {
                    task.Refresh();
                }

                this.UnblockUi();
            });
        }

        public void RefreshTasks()
        {
            foreach (var task in this.tasks)
            {
                task.Refresh();
            }
        }

        protected override void InititalizeCommands()
        {
            base.InititalizeCommands();
            this.EditTaskCommand = new RelayCommand(this.EditTask, this.CanEditTask);
            this.UpdateWorkItemsCommand = new RelayCommand(this.UpdateWorkItems);
            this.AddNewTaskCommand = new RelayCommand(this.AddNewTask);
        }

        protected override void HandlePropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.HandlePropertyChanged(sender, e);
            switch (e.PropertyName)
            {
                case "SelectedTask":
                    this.EditTaskCommand.RaiseCanExecuteChanged();
                    break;
            }
        }
    }
}
